﻿//Include("Mz.String");

/**
 * @fileoverview 格式化一个字符串.字符串中需要替换部分的格式是#{prop_name}.
 * 最后会被o[prop_name]的值替换。如果o[prop_name]为空的话，实际被替换的内容为空
 * 如果o[prop_name]是一个函数的话，就会把prop_name做为参数传递过去，并用返回值替换#{prop_name}所在的位置
 * 如果o[prop_name]不是函数的话，就会用o[prop_name]的值替换#{prop_name}所在的位置.
 * @author meizz
 * @version 20090426
 *
 * @name Mz.String.format
 * @namespace Mz.String.format
 * @param {String} str 需要格式化的字符串
 * @param {Object} json 需要提供相应数据的对象
 * @return {String} 格式化之后的字符串
 */
Mz.String.format = function(str, json){
    if(arguments.length > 1){
        var m = Mz.format,
            k = /([.*+?^=!:${}()|[\]\/\\])/g,
            l = (m.left_delimiter || "{").replace(k, "\\$1"),
            r = (m.right_delimiter || "}").replace(k, "\\$1");
        var r1 = m._r1 || (m._r1 = new RegExp("#" + l + "([^" + l + r + "]+)" + r, "g")),
            r2 = m._r2 || (m._r2 = new RegExp("#" + l + "(\\d+)" + r, "g"));
        if(typeof(json) == "object"){
            return str.replace(r1, function(a, key) {
              var v = json[key];
              if(typeof v == 'function'){
                v = v(key);
            }
            return typeof(v) == 'undefined' ? "" : v;
          });
        }else if(typeof(json) != "undefined"){
            // [$1,$$,$_,$1,$2,$3,$4,$5,$6,$7,$8,$9,$`,$&,$+,$']
            // fix this bug by dongjie 20081006
            // THANKS:liangdongjie@baidu.com
            // 感谢dongjie发现了这个问题并给出了解决的方案
            var vs = Array.prototype.slice.call(arguments, 1);
            var vl = vs.length;
            return str.replace(r2, function(a, index){
                index = parseInt(index, 10);
                return (index >= vl) ? a : vs[index];
            });
        }
    }
    return str;
};

/**
 * 设置Mz.format函数所用的分割符号，默认是{, }
 * 因为Mz.format中所使用的正则是#{..}，如果不想用{}，那么
 * 可以通过这个函数来设置。现在主要供baike使用。
 * @param {String} [left] 左侧的分割符号，长度是1
 * @param {String} [right] 右侧的分割符号，长度是1。如果没有这个参数的话，默认值是left，如果left没有的话，默认值是}
 * */
Mz.format.delimiter = function(left, right){
    var me = Mz.format;
    me.left_delimiter = left || "{";
    me.right_delimiter = right || left || "}";
    me._r1 = me._r2 = null;
};
